Общие настройки
Сервисы интеграции – это встроенные в sink компоненты, реализующие логику интеграции агента с внешними системами, передающие результаты работы sink во внешнюю систему. Все сервисы имеют базовую конфигурацию для подключения интегрируемого сервера по его адресу, порту и требуемому типу аутентификации (basic, bearer, token) с возможностью настройки протокола связи (http, https) и возможностью отключения проверки SSL-сертификата. Реализованы сервисы интеграции со следующими системами:
- Kaspersky Cybertrace;
- PT NAD;
- MISP;
- RuSIEM;
- UserGate.
Остальные интеграции реализованы через загрузку файла, сформированного агентом. Загрузка этого файла осуществляется средствами внешней системы или напрямую, без использования агентского приложения.
Чтобы использовать конкретную конфигурацию пайплайна вместо базовой, необходимо в файле docker-compose.yml заменить путь ./pkl/configs/base_pipeline.pkl на путь к нужному файлу, например, ./pkl/configs/cybertrace_pipeline.pkl.
Переменные окружения
В общем случае необходимо определить следующие переменные окружения:
Основные переменные для подключения к Solar TI Feeds
- TIC_AGENT_API_SERVER=api.data.rt-solar.ru - Адрес сервера Solar TI Feeds
- TIC_AGENT_API_TOKEN - JWT-токен для аутентификации на сервере Solar TI Feeds
- TIC_AGENT_NOTIFICATION_SERVER=notifications.data.rt-solar.ru - Адрес сервера уведомлений
Настройки локального хранилища и путей (опционально)
- TIC_AGENT_SQLITE_DB_FILE=/data/agent/states.sqlite - Полный путь к файлу базы данных SQLite для хранения состояния работы агента
- TIC_AGENT_OUTPUT_DIR=/data/agent/data - Директория для сохранения результирующих файлов (CSV, TXT)
- TIC_AGENT_LOG_DIR=/data/agent/ - Директория для хранения лог-файлов работы агента
По умолчанию путь /data/agent/ монтируется в локальную папку ./work.
Конфигурации внешних сервисов
Конфигурация ServiceConfig определяет параметры для взаимодействия с внешним сервисом. Обязательные для заполнения поля credentials и address поддерживают различные настройки:
- credentials — принимает объект одной из трёх схем аутентификации: Basic, Bearer или Token.
- address — содержит параметры сетевого подключения, подробно описанные в отдельной таблице ниже.
Параметры конфигурации ServiceConfig
| Параметр | Тип данных | Значение по умолчанию | Обязательность | Описание | Пример |
|---|---|---|---|---|---|
| credentials | Credentials | Да | Данные для аутентификации | credentials = new agent.Basic {username = cyberTraceUser password = cyberTracePassword} | |
| address | Address | Да | Данные подключения | address {host = cyberTraceHost port = cyberTracePort insecureSkipVerify = true scheme = "https"} | |
| timeout | Duration | 30.s | Нет | Таймаут запросов | 60.s |
| listName | String | Да | Имя списка для загрузки данных | “4rays_feeds” |
Параметры конфигурации Basic
| Параметр | Тип данных | Обязательность | Описание |
|---|---|---|---|
| username | String | Да | Имя пользователя |
| password | String | Да | Пароль |
Параметры конфигурации Bearer
| Параметр | Тип данных | Обязательность | Описание |
|---|---|---|---|
| bearerToken | String | Да | Bearer токен без префикса Bearer |
Параметры конфигурации Token
| Параметр | Тип данных | Обязательность | Описание |
|---|---|---|---|
| token | String | Да | Токен доступа |
Параметры конфигурации Address
| Параметр | Тип данных | Значение по умолчанию | Обязательность | Описание | Пример |
|---|---|---|---|---|---|
| host | String | Да | Адрес внешнего сервера | example.com | |
| port | String | Да | Порт внешнего сервера | 8080 | |
| scheme | String | https | Нет | Схема подключения к серверу, возможные значения: http, https | http |
| insecureSkipVerify | Boolean | false | Нет | Отключение проверки SSL-сертификата сервера | true |
Пример базового конфигурационного файла
В данном конфигурационном файле описан пайплайн по выгрузке отдельных потоков сетевых индикаторов по каждому из фидов, перечисленных в локальной переменной feedsList, в виде подписки на изменения с сохранением данных в CSV необходимого формата, который формируется в IndicatorsTextMap -> fielsdMap.
Для изменения списка выгружаемых фидов необходимо изменить состав значений в feedsList. Для выбора других типов индикаторов – FeedsStreamGenerator -> filter -> types, изменение других параметров запроса API находится в том же блоке filter.
Основные параметры конфигурации в виде адреса сервера, токена и локальных путей читаются из переменных окружения, и вынесены в отдельный блок описания локальных переменных для уменьшения дублирования значений в объявлении самого пайплайна.
amends "package://pkg.pkl-lang.org/github.com/pipelane/pipelaner/pipelaner@1.3.1#/Pipelaner.pkl"
import "package://pkg.pkl-lang.org/github.com/pipelane/pipelaner/pipelaner@1.3.1#/source/Components.pkl"
import "../agent.pkl"
import "../templates.pkl"
local feedsList = templates.allFeedsList.map((it) -> it.toLowerCase())
local outputDir = "/data/agent"
local ouptputFileName = "ioc.csv"
pipelines {
new Components.Pipeline {
name = "base_config"
inputs {
new agent.FeedStreamGenerator {
name = "indicators-generator"
server = templates.serverEnvCfg
schedule = templates.scheduleCronMinCfg
filter = new agent.IndicatorRequestParams {
types = List("ipv4-addr", "ipv6-addr", "domain-name", "url")
feedNames = feedsList
actions = List("create", "update", "delete")
fields = List("indicator_id", "value", "indicator_type", "valid_until", "first_seen", "action", "external_references", "categories", "last_seen", "relations", "description", "rules", "feeds", "zone")
iter {
limit = 1000
}
}
sqlite = templates.sqliteEnvCfg
}
}
transforms {
new agent.IndicatorsTextMap {
name = "indicators-map"
inputs {
"indicators-generator"
}
fieldsMap {
["FeedSource"] = """
"ti_cloud"
"""
["IndicatorID"] = "IndicatorID"
["IndicatorType"] = "IndicatorType"
["Action"] = "Action"
["UpdatedAt"] = "UpdatedAt"
["Value"] = "Value"
["Description"] = "Description"
["FirstSeen"] = "FirstSeen"
["LastSeen"] = "LastSeen"
["ValidUntil"] = "ValidUntil"
["Relations"] = """
len(Relations) > 0 ? Relations : ""
"""
["RelatedReports"] = """
let reports = map(Relations, {#.ObjectType == "report" ? #.ObjectValue : ""});
join(filter(reports, {# != ""}), ",")
"""
["RelatedThreatActors"] = """
let actors = map(Relations, {#.ObjectType == "threat-actor" ? #.ObjectValue : ""});
join(filter(actors, {# != ""}), ",")
"""
["RelatedMalware"] = """
let malware = map(Relations, {#.ObjectType == "malware" ? #.ObjectValue : ""});
join(filter(malware, {# != ""}), ",")
"""
["RelatedTools"] = """
let tools = map(Relations, {#.ObjectType == "tool" ? #.ObjectValue: ""});
join(filter(tools, {# != ""}), ",")
"""
["RelatedFiles"] = """
let files = map(Relations, let x = #; x.ObjectType == "file" ? x.ObjectValue : "");
join(filter(files, {# != ""}), ",")
"""
["RelatedIndicators"] = """
let indicators = map(Relations, let x = #; x.ObjectType == "indicator" ? x.IndicatorType +":" + x.ObjectValue : "");
join(filter(indicators, {# != ""}), ",")
"""
["ExternalReferences"] = "ExternalReferences"
["Rules"] = "Rules"
["Categories"] = "Categories"
["Feeds"] = "Feeds"
["Zone"] = "Zone"
}
}
}
sinks {
new agent.IndicatorsTextSink {
name = "indicators-sinks"
inputs {
"indicators-map"
}
writer {
outputDirectory = outputDir
outputFileName = ouptputFileName
writeMode = "rolling"
fileFormat = "csv"
writeHeaders = true
separator = ","
quote = "\""
allQuotes = true
}
sqlite = templates.sqliteEnvCfg
}
}
}
}
settings = templates.baseSettings